package org.net5ijy.security.controller;

import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;

import org.net5ijy.security.bean.Role;
import org.net5ijy.security.bean.User;
import org.net5ijy.security.service.RoleService;
import org.net5ijy.security.service.UserService;
import org.net5ijy.security.util.PageResult;
import org.net5ijy.security.util.ResponseMessage;
import org.net5ijy.security.util.exception.UserNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * UserController
 *
 * @author XGF
 * @date 2020/11/30 22:38
 */
@Controller
@RequestMapping("/user")
public class UserController {

  @Autowired
  private UserService userService;

  @Autowired
  private RoleService roleService;

  @RequestMapping(value = "/users", method = RequestMethod.GET)
  public ModelAndView users(
      @RequestParam(defaultValue = "1") Integer page,
      @RequestParam(defaultValue = "5") Integer size) {
    PageResult<User> pageUsers = userService.getPageUsers(page, size);
    ModelAndView model = new ModelAndView("user/users");
    model.addObject("userResult", pageUsers);
    model.addObject("size", size);
    return model;
  }

  @RequestMapping(value = "/add", method = RequestMethod.GET)
  public ModelAndView add() {
    ModelAndView model = new ModelAndView("user/add");
    // 获取所有角色
    List<Role> roles = roleService.getRoles();
    model.addObject("roles", roles);
    // 拥有的角色
    model.addObject("roleIds", new ArrayList<Integer>());
    return model;
  }

  @RequestMapping(value = "/add", method = RequestMethod.POST)
  public ModelAndView add(@RequestParam("roleIds") List<Integer> roleIds,
      @Valid User user, BindingResult result) {

    // 获取验证信息
    ModelAndView validErrorView = validateUser(user, result);
    if (validErrorView != null) {
      validErrorView.setViewName("user/add");
      // 用户数据回显
      validErrorView.addObject("user", user);
      // 获取所有角色
      List<Role> roles = roleService.getRoles();
      validErrorView.addObject("roles", roles);
      // 选择的角色
      validErrorView.addObject("roleIds", roleIds);
      return validErrorView;
    }
    // 给用户添加角色
    for (Integer roleId : roleIds) {
      user.getRoles().add(new Role(roleId));
    }
    // 添加用户
    userService.saveUser(user);
    return new ModelAndView("redirect:/user/users");
  }

  @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
  public ModelAndView edit(@PathVariable Integer id) {

    ModelAndView model = new ModelAndView("user/edit");
    // 获取修改的用户数据
    User user = userService.getUser(id);
    // 用户数据回显
    model.addObject("user", user);
    // 获取所有角色
    List<Role> roles = roleService.getRoles();
    model.addObject("roles", roles);
    // 封装用户拥有的角色id
    List<Integer> roleIds = new ArrayList<Integer>();
    for (Role role : user.getRoles()) {
      roleIds.add(role.getId());
    }
    model.addObject("roleIds", roleIds);
    return model;
  }

  @RequestMapping(value = "/edit", method = RequestMethod.POST)
  public ModelAndView edit(
      @RequestParam("roleIds") List<Integer> roleIds,
      @Valid User user, BindingResult result) {

    // 获取验证信息
    ModelAndView validErrorView = validateUser(user, result);
    if (validErrorView != null) {
      validErrorView.setViewName("user/edit");
      // 用户数据回显
      validErrorView.addObject("user", user);
      // 获取所有角色
      List<Role> roles = roleService.getRoles();
      validErrorView.addObject("roles", roles);
      // 选择的角色
      validErrorView.addObject("roleIds", roleIds);
      return validErrorView;
    }
    // 给用户添加角色
    for (Integer roleId : roleIds) {
      user.getRoles().add(new Role(roleId));
    }
    // 修改用户
    userService.updateUser(user);
    return new ModelAndView("redirect:/user/users");
  }

  /**
   * 删除指定id的用户数据<br /> <br />
   *
   * 编写测试用例注意的点：<br />
   *
   * 1. 正常存在的数据<br />
   *
   * 2. 不存在的数据<br />
   *
   * 3. 存在，但是有外键关联的数据<br />
   *
   * @param id - 指定id
   * @return ResponseMessage对象
   * @author 创建人：xuguofeng
   */
  @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
  @ResponseBody
  public ResponseMessage delete(@PathVariable Integer id) {
    // 测试抛出异常
    if (id == 100000000) {
      throw new UserNotFoundException(id);
    }
    userService.deleteUser(id);
    return ResponseMessage.success();
  }

  private ModelAndView validateUser(User user, BindingResult result) {
    List<FieldError> fieldErrors = result.getFieldErrors();
    StringBuilder builder = new StringBuilder();
    if (!fieldErrors.isEmpty()) {
      for (FieldError fe : fieldErrors) {
        builder.append(fe.getDefaultMessage());
        builder.append("；<br />");
      }
      ModelAndView model = new ModelAndView();
      model.addObject("errorMsg", builder.toString());
      return model;
    }
    return null;
  }

  // 添加测试数据 - start
  // for (int k = 1; k <= 100; k++) {
  // user.setUsername(String.format("admin%03d", k));
  // user.setMobile(String.format("189%08d", k));
  // user.setEmail(String.format("189%08d@189.cn", k));
  // userService.saveUser(user);
  // }
  // 添加测试数据 - end
}
